{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Eigenvalue problem\n", "==================" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Matrix transformaion is written as\n", "\n", "$$ \\mathbf{y} = A\\mathbf{x} $$\n", "\n", "A different vector in the same direction can be written as scalar multiplication:\n", "\n", "$$\\mathbf{y} = \\lambda\\mathbf{x}$$ \n", "\n", "Equating these $y$s yields:\n", "\n", "$$ A\\mathbf{x} = \\lambda \\mathbf{x} \\Rightarrow (A - \\lambda I) \\mathbf{x} = 0$$\n", "\n", "$$\\det(A - \\lambda I) = 0 $$\n", "\n", "The eigenvalue problem can also be collected with $\\Lambda$ being a diagonal matrix containing all the eigenvalues and $X$ containing the eigenvectors stacked column-wise. This leads to the eigenvalue decomposition:\n", "\n", "$$ A X = X \\Lambda \\Rightarrow A = X \\Lambda X^{-1}$$\n", "\n", "with\n", "\n", "$$ \\Lambda = diag(\\lambda_i)$$\n", "\n", "If we try to find a similar decomposition with different constraints, we can write\n", "\n", "$$ A = U D V^{H} $$\n", "\n", "If $D$ is a diagonal matrix and $U$ and $V$ are [unitary](http://en.wikipedia.org/wiki/Unitary_matrix), this is the singular value decomposition.\n", "\n", "In Skogestad \n", "\n", "$$ A = U \\Sigma V^{H} $$\n", "\n", "$$ \\Sigma = diag(\\sigma_i)$$\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from ipywidgets import interact" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def plotvector(x, color='blue'):\n", " plt.plot([0, x[0,0]], [0, x[1,0]], color=color)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "import matplotlib.patches as patches" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's investigate the properties of this matrix:" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [], "source": [ "A = numpy.matrix([[4, 3],\n", " [2, 1]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The eigenvectors and eigenvalues can be calculated as follows. We also calculate the output vectors associated with a unit vector input in the eigenvector directions." ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "matrix([[4, 3],\n", " [2, 1]])" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [], "source": [ "v = numpy.asmatrix(numpy.random.random(2)).T" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "matrix([[0.89474813],\n", " [0.44657115]])" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v = A*v\n", "\n", "v = v/numpy.linalg.norm(v)\n", "v" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [], "source": [ "lambdas, eigvectors = numpy.linalg.eig(A)\n", "ev1 = lambdas[0]*eigvectors[:, 0]\n", "ev2 = lambdas[1]*eigvectors[:, 1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The singular values determine the main axes of the translation ellipse of the matrix. Note that the `numpy.linalg.svd` function returns the conjugate transpose of the input direction matrix." ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [], "source": [ "U, S, VH = numpy.linalg.svd(A)\n", "V = VH.H\n", "ellipseangle = numpy.rad2deg(numpy.angle(complex(*U[:, 0])))" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "412b4de2897149439ff0ce2a158eb4df", "version_major": 2, "version_minor": 0 }, "text/html": [ "
Failed to display Jupyter Widget of type interactive.
\n", " If you're reading this message in the Jupyter Notebook or JupyterLab Notebook, it may mean\n", " that the widgets JavaScript is still loading. If this message persists, it\n", " likely means that the widgets JavaScript library is either not installed or\n", " not enabled. See the Jupyter\n", " Widgets Documentation for setup instructions.\n", "
\n", "\n", " If you're reading this message in another frontend (for example, a static\n", " rendering on GitHub or NBViewer),\n", " it may mean that your frontend doesn't currently support widgets.\n", "
\n" ], "text/plain": [ "interactive(children=(FloatSlider(value=5.5, description='scale', max=10.0, min=1.0), FloatSlider(value=3.141592653589793, description='theta', max=6.283185307179586), Output()), _dom_classes=('widget-interact',))" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "